--- title: "4、方格分割" created: 2025-11-28 tags: - 算法 --- # 4、方格分割 ## 题目 [方格分割](https://www.lanqiao.cn/paper/3854/problem/644/) ![[image-b1e91fbf.png]] ## 思路分析 两部分是围绕中心点对称的 想法是 用1表示一种颜色 0表示另一种颜色 枚举所有的排列情况 然后找到所有应该对称的下标组 对他们进行判断 如果发现某位置的对应位置不是相反 就直接continue 如果所有对称位置都符合01相反 就说明是一个可行方案 ![[image-c5fc6cc1.png]] a[i][j]应该要与a[7-i][7-j]对称 但是不好对每个方格放01进行枚举 想了一下 可以转换成一维 用二进制数来枚举 ![[image-3bbe6bd8.png]] ![[image-53326c15.png]] 因为二进制数每一位都是0或1 那么从0枚举到2^36 就可以考虑到所有的排列组合 看某个方案是否满足 只需要看某一位 和它对应的那一位为是否不一样即可 对应关系如下: ![[image-c5cb49e8.png]] 然后实际上二进制是从第0位开始的 所以关系应该是 i:36-i 所以得到以下代码 ```cpp #include using namespace std; int main() { long long cnt=0; for(long long i=0;i<(1LL<<36);i++){ bool success=true; for(int d=0;d<18;d++){ long long curd = (i >> d) & 1LL; long long backd = (i >> (35 - d)) & 1LL; if(curd==backd){ success=false; break; } } if(success) cnt++; } cout< using namespace std; #define endl '\n' const int N=7;//0~6 bool st[N][N]; int dx[4]={-1,0,1,0}; int dy[4]={0,1,0,-1}; int res=0; int n; bool isVaild(int x,int y){ return x>=0 && x<=N-1 && y>=0 && y<=N-1 && !st[x][y]; } void dfs(int x,int y){ if(x==0 || x==n || y==0 || y==n){ res++; return; } for(int i=0;i<4;i++){ int nx=x+dx[i],ny=y+dy[i]; if(isVaild(nx,ny) && isVaild(n-nx,n-ny)){ st[nx][ny]=st[n-nx][n-ny]=true; dfs(nx,ny); st[nx][ny]=st[n-nx][n-ny]=false;//该点可以走多次 需要回溯 } } } int main() { ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); n=N-1; st[n/2][n/2]=true; dfs(n/2,n/2); cout<